package cn.edu.xmist.expression;

import cn.edu.xmist.conduct.*;
import cn.edu.xmist.constant.ConfigConstant;
import cn.edu.xmist.utils.PictureUtil;
import cn.edu.xmist.utils.SoundUtil;
import org.lwjgl.input.Keyboard;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author honeyrr
 *	窗口类
 */
public class GameWindow extends AbstractWindow {

	private P1Tank tank;
	private CopyOnWriteArrayList<AbstractPicture> bpList = new CopyOnWriteArrayList<>();
	private ArrayList<EnemyTank> tcList = new ArrayList<>();
	
	public GameWindow(String title, int width, int height, int fps) {
		super(title, width, height, fps);
	}

	/**
	 * 窗口创建时的回调
	 */
	@Override
	protected void onCreate() {
		tank = new P1Tank((ConfigConstant.WindowConstant.WIDTH - 64) / 2, ConfigConstant.WindowConstant.HEIGHT - 64);
		addPicture(tank);
		
		// 添加墙、铁、水、草
		for (int i = 0; i < 18; i++) {
			addPicture(new Wall(i * 64, 64 * 2));
		}
		for (int i = 1; i < 17; i++) {
			addPicture(new Water(i * 64, 64 * 3));
		}
		for (int i = 0; i < 18; i++) {
			if (i >= 7 && i <= 10) {
				continue;
			}
			addPicture(new Grass(i * 64, 64 * 5));
		}
		for (int i = 3; i < 15; i++) {
			addPicture(new Steel(i * 64, 64 * 7));
		}
		
		SoundUtil.play(ConfigConstant.START);
		
		// 生成随机位置的9个电脑坦克
		for(int i = 0; i < 9; i++) {
			EnemyTank enemyTank = new EnemyTank((i * 3) * 64, new Random().nextInt(64));
			addPicture(enemyTank);
			tcList.add(enemyTank);
		}
	}

	/**
	 * 鼠标事件的监听
	 */
	@Override
	protected void onMouseEvent(int key, int x, int y) {

	}

	/**
	 * 键盘事件的监听
	 */
	@Override
	protected void onKeyEvent(int key) {
		switch (key) {
		case Keyboard.KEY_UP:
			tank.move(Direction.UP);
			break;
		case Keyboard.KEY_DOWN:
			tank.move(Direction.DOWN);
			break;
		case Keyboard.KEY_LEFT:
			tank.move(Direction.LEFT);
			break;
		case Keyboard.KEY_RIGHT:
			tank.move(Direction.RIGHT);
			break;
		case Keyboard.KEY_SPACE:
			// 当我方坦克血量不为0时，才能发射子弹
			if (!tank.isDestroyed()) {
				Bullet bullet = tank.shotBullet();
				if (bullet != null) {
					addPicture(bullet);
				}
			}
			break;

		default:
			break;
		}
	}

	/**
	 * 刷新方法每秒刷新Config.FPS次
	 */
	@Override
	protected void onDisplayUpdate() {
		// 游戏状态，是赢还是输
		gameState();
		
		// 用循环遍历将图形绘制出来
		for (AbstractPicture bp : bpList) {
			bp.draw();
			if (bp instanceof Destroyable) {
				if (((Destroyable) bp).isDestroyed()) {
					bpList.remove(bp);
					if (bp instanceof Blockable) {
						SoundUtil.play(ConfigConstant.BLAST);
					}
					if (bp instanceof EnemyTank) {
						tcList.remove((Destroyable)bp);
					}
				}
			}
		}
		
		// 坦克与墙铁水发生碰撞
		for (AbstractPicture bp1 : bpList) {
			for (AbstractPicture bp2 : bpList) {
				if(bp1 instanceof Moveable && bp2 instanceof Blockable && bp1 != bp2) {
					if (((Moveable)bp1).moveHit((Blockable)bp2)) {
						
						// 电脑坦克相互碰撞之后掉头
						if (bp1 instanceof EnemyTank && bp2 instanceof EnemyTank) {
							((EnemyTank)bp1).setDircetion(reverDirection(((EnemyTank)bp2).getDircetion()));
						}
						
						// 电脑坦克碰墙之后立马换方向
						if (bp1 instanceof EnemyTank && (bp2 instanceof Steel || bp2 instanceof Wall || bp2 instanceof Water)) {
							getRandomDirection();
							((EnemyTank)bp1).setDircetion(this.dircetion);
						}
						
						// 子弹打到敌方坦克，敌方坦克掉头跑
						if (bp1 instanceof Bullet && bp2 instanceof EnemyTank) {
							((EnemyTank)bp2).setDircetion(reverDirection(((Bullet)bp1).getDircetion()));
						}
						break;
					}
				}
			}
		}
		// 子弹与墙铁水发生碰撞
		for (AbstractPicture bp1 : bpList) {
			for (AbstractPicture bp2 : bpList) {
				if(bp1 instanceof Attackable && bp2 instanceof Hitable) {
					if (((Attackable)bp1).checkHit((Hitable)bp2)) {
						bpList.remove(bp1);
						Blast blast = ((Hitable)bp2).showBlast();
						bpList.add(blast);
						if (bp2 instanceof EnemyBullet || bp2 instanceof Bullet) {
							bpList.remove(bp2);
						}
						break;// 当子弹打中两块砖之间是，只有拿到其中一块就跳出循环
					}
				}
			}
		}
		
		// 找到电脑坦克，让其自动游走并攻击
		for (AbstractPicture bp : bpList) {
			if (bp instanceof EnemyTank) {
				((EnemyTank) bp).move();
				EnemyBullet enemyBullet = ((EnemyTank) bp).shotBullet();
				if (enemyBullet != null) {
					addPicture(enemyBullet);
				}
			}
		}
		System.out.println(bpList.size());
	}

	/**
	 * 反方向
	 * @param dircetion
	 * @return
	 */
	private Direction reverDirection(Direction dircetion) {
		if (dircetion == Direction.UP) {
			return Direction.DOWN;
		} else if (dircetion == Direction.DOWN) {
			return Direction.UP;
		} else if (dircetion == Direction.LEFT) {
			return Direction.RIGHT;
		} else {
			return Direction.LEFT;
		}
		
	}

	
	private Random random = new Random();
	private Direction dircetion;
	
	/**
	 * 生成随机方向
	 */
	private void getRandomDirection() {
		int i = random.nextInt(4);
		if (i == 1) {
			this.dircetion = Direction.UP;
		} else if (i == 2) {
			this.dircetion = Direction.DOWN;
		} else if (i == 3) {
			this.dircetion = Direction.LEFT;
		} else {
			this.dircetion = Direction.RIGHT;
		}
	}
	/**
	 * 游戏状态
	 */
	private void gameState() {
		if (tank.isDestroyed() || (tank.isDestroyed() && tcList.size() == 0)) {
			bpList.clear();
			PictureUtil.draw(ConfigConstant.OVER, 0, 0);
			PictureUtil.exitGame();
		}
		if (tcList.size() == 0) {
			bpList.clear();
			PictureUtil.draw(ConfigConstant.WIN, 0, 0);
			PictureUtil.exitGame();
		}
	}
	
	private void addPicture(AbstractPicture bp) {
		bpList.add(bp);
		// 按规则排序
		bpList.sort(new Comparator<AbstractPicture>() {

			@Override
			public int compare(AbstractPicture o1, AbstractPicture o2) {
				// TODO 自动生成的方法存根
				return o1.getOrder() - o2.getOrder();
			}
		});
	}

}
